package com.hruiworks.campusgroup.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hruiworks.campusgroup.dao.mapper.AdministratorMapper;
import com.hruiworks.campusgroup.enums.ErrorCode;
import com.hruiworks.campusgroup.exception.BusinessException;
import com.hruiworks.campusgroup.pojo.entity.Administrator;
import com.hruiworks.campusgroup.pojo.request.AdministratorCreateRequest;
import com.hruiworks.campusgroup.pojo.request.AdministratorUpdateRequest;
import com.hruiworks.campusgroup.pojo.vo.AdministratorInfoVo;
import com.hruiworks.campusgroup.service.AdministratorService;
import com.hruiworks.usercheck.pojo.entity.JwtEntity;
import com.hruiworks.usercheck.util.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;

import static com.hruiworks.campusgroup.constants.AdministratorConstant.*;
import static com.hruiworks.usercheck.enums.MessageDigestAlgorithmEnum.SHA256;

/**
 * @author jiushui
 * @description 针对表【administrator(管理员表)】的数据库操作Service实现
 * @createDate 2025-02-13 09:44:00
 */
@Slf4j
@Service
public class AdministratorServiceImpl extends ServiceImpl<AdministratorMapper, Administrator>
        implements AdministratorService {

    // 加盐
    private static final String SALT = "dDWw8d9mw*qzr34,mx1xb=1";

    @Resource
    private AdministratorMapper administratorMapper;

    @Override
    public AdministratorInfoVo createAdministrator(AdministratorCreateRequest administratorCreateRequest, Long administratorId) {


        // 1. 获取当前登录管理员的信息
        Administrator administrator = administratorMapper.selectById(administratorId);

        // 2. 权限不足不允许创建
        if (administrator.getLevel() >= ADMINISTRATOR_LEVEL_2) {
            throw new BusinessException(ErrorCode.FORBIDDEN, "没有创建管理员权限");
        }

        // 3. 检验参数是否有空值
        if (ParamUtils.isAnyBlank(administratorCreateRequest)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "存在参数为空");
        }

        // 4. 创建新的管理员
        String password = administratorCreateRequest.getPassword();
        Administrator newAdministrator = new Administrator();
        BeanUtils.copyProperties(administratorCreateRequest, newAdministrator);
        newAdministrator.setParent(administratorId);
        newAdministrator.setLevel(administrator.getLevel() + 1);
        newAdministrator.setPassword(PasswordUtils.encryptPassword(password, SALT, SHA256));

        // 5. 根据权限不同修改部分信息
        if (Objects.equals(administrator.getLevel(), ADMINISTRATOR_LEVEL_1)) {
            newAdministrator.setUniversity(administrator.getUniversity());
        }

        // 6. 校验用户名是否合法(只允许数字、字母、下划线)
        if (!UsernameUtils.onlyNumLetterUnderscore(newAdministrator.getUsername())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户名只允许数字、字母、下划线");
        }
        // 7. 校验用户名长度是否合法
        if (!StringUtils.strLengthBetween(newAdministrator.getUsername(), 4, 20)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户名应该在4位(含)和20位(含)之间");
        }

        // 8. 手机号校验
        if (!PhoneNumberUtils.isIllegalChinaPhoneNumber(newAdministrator.getPhone())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "手机号码不合法");
        }

        // 9. 邮箱校验
        if (!EmailUtils.isIllegalEmail(newAdministrator.getEmail())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "邮箱地址不合法");
        }

        // 10. 查看用户名是否重复
        LambdaQueryWrapper<Administrator> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Administrator::getUsername, newAdministrator.getUsername());
        Long count = administratorMapper.selectCount(queryWrapper);
        if (count > 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号重复");
        }

        int insert = administratorMapper.insert(newAdministrator);

        if (insert != 1) {
            throw new BusinessException(ErrorCode.OTHER_ERROR, "创建失败，检查后端日志");
        }

        // 11. 返回信息
        AdministratorInfoVo administratorInfoVo = new AdministratorInfoVo();
        BeanUtils.copyProperties(newAdministrator, administratorInfoVo);
        administratorInfoVo.setPassword(password);
        return administratorInfoVo;
    }

    @Override
    public JwtEntity administratorLogin(String username, String password) {

        // 1. 校验参数是否有空值
        if (ParamUtils.isAnyBlank(username, password)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
        }

        // 2. 密码加密，之后用于比较
        String encryptedPassword = PasswordUtils.encryptPassword(password, SALT, SHA256);

        // 3. 查询数据库
        LambdaQueryWrapper<Administrator> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Administrator::getUsername, username);
        Administrator administrator = administratorMapper.selectOne(queryWrapper);

        // 4. 校验管理员密码
        if (Objects.isNull(administrator) || !PasswordUtils.comparePassword(encryptedPassword, administrator.getPassword())) {
            log.info("login failed, administrator is not exited or wrong password");
            throw new BusinessException(ErrorCode.NULL_ERROR, "用户不存在或密码错误");
        }

        // 5 生成jwt
        Administrator jwtAdministrator = new Administrator();
        jwtAdministrator.setId(administrator.getId());
        jwtAdministrator.setUsername(administrator.getUsername());
        jwtAdministrator.setLevel(administrator.getLevel());
        jwtAdministrator.setParent(administrator.getParent());
        jwtAdministrator.setUniversity(administrator.getUniversity());

        return JwtUtils.generateHs256Jwt(jwtAdministrator, 1, ChronoUnit.WEEKS);
    }

    @Override
    public boolean deleteAdministrator(Long currentAdministratorId, Long targetAdministratorId) {

        Administrator administrator = administratorMapper.selectById(currentAdministratorId);
        Integer currentLevel = administrator.getLevel();
        // 对于不同权限等级的管理员有不同的操作
        // 1. 对于最高等级：level0的管理员，只能回收level1的管理员，且回收某个level1的管理员，应该一并其签发的level2的管理员进行回收
        if (ADMINISTRATOR_LEVEL_0.equals(currentLevel)) {
            LambdaQueryWrapper<Administrator> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Administrator::getId, targetAdministratorId)
                    .eq(Administrator::getLevel, currentLevel + 1)
                    .or()
                    .eq(Administrator::getParent, targetAdministratorId)
                    .eq(Administrator::getLevel, currentLevel + 2);
            int delete = administratorMapper.delete(queryWrapper);
            // 大于0说明删除成功
            return delete > 0;
        }

        // 2. 对于level1的管理员，只能回收level2的管理员，且只能回收本校的管理员
        else if (ADMINISTRATOR_LEVEL_1.equals(currentLevel)) {
            LambdaQueryWrapper<Administrator> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Administrator::getId, targetAdministratorId)
                    .eq(Administrator::getLevel, currentLevel + 1)
                    .eq(Administrator::getUniversity, administrator.getUniversity());
            int delete = administratorMapper.delete(queryWrapper);
            return delete > 0;
        } else throw new BusinessException(ErrorCode.FORBIDDEN, "没有删除权限");
    }

    @Override
    public Integer updateAdministrator(AdministratorUpdateRequest administratorUpdateRequest, Long currentAdministratorId) {

        Administrator administrator = new Administrator();
        administrator.setId(currentAdministratorId);
        administrator.setPassword(PasswordUtils.encryptPassword(administratorUpdateRequest.getPassword(), SALT, SHA256));

        return administratorMapper.updateById(administrator);
        
    }

    @Override
    public AdministratorInfoVo getCurrentAdministratorInfo(Long administratorId) {
        Administrator administrator = administratorMapper.selectById(administratorId);
        AdministratorInfoVo administratorInfoVo = new AdministratorInfoVo();
        BeanUtils.copyProperties(administrator,administratorInfoVo);
        administratorInfoVo.setPassword(null);
        return administratorInfoVo;
    }

    @Override
    public List<AdministratorInfoVo> listAdministratorInfo(Administrator currentAdministrator, String searchValue) {
        LambdaQueryWrapper<Administrator> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Administrator::getParent, currentAdministrator.getId());
        if (org.apache.commons.lang3.StringUtils.isNotBlank(searchValue)) {
            queryWrapper.and(qw->qw.like(Administrator::getRealName, searchValue).or().like(Administrator::getUniversity, searchValue));

        }
        List<Administrator> administrators = administratorMapper.selectList(queryWrapper);
        return administrators.stream().map(administrator -> {
            AdministratorInfoVo administratorInfoVo = new AdministratorInfoVo();
            BeanUtils.copyProperties(administrator, administratorInfoVo);
            administratorInfoVo.setPassword(null);
            return administratorInfoVo;
        }).toList();
    }


}




